package com.base.http
import android.util.LruCache
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory

/**
 * Http请求辅助类
 */
object HttpHelper{
    private val retrofitCache: LruCache<String,Retrofit> by lazy { LruCache<String,Retrofit>(5) }
    private val apiCache: LruCache<Class<*>,Any?> by lazy { LruCache<Class<*>,Any?>(10) }
    private const val url = ""

    /**
     * 调用Api
     */
    fun <I> api(service: Class<I>, baseUrl: String = url, client: OkHttpClient = createHttpClient()): I {
        return apiCache[service] as? I ?: createApi(service, baseUrl, client)
    }

    /**
     * 创建Retrofit
     */
    private fun createRetrofit(key: String,url: String, client: OkHttpClient): Retrofit {
        val retrofit = Retrofit.Builder()
            .client(client)
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
        retrofitCache.put(key,retrofit)
        return retrofit
    }

    /**
     * 创建Client
     */
    private fun createHttpClient(): OkHttpClient {
        return OkHttpClient.Builder() // 创建httpClient
            .cookieJar(ICookieJar) //Cookie管理
            .addInterceptor(IInterceptor) // 设置拦截器
            .build()
    }

    /**
     * 创建Api
     */
    private fun <I> createApi(service: Class<I>,baseUrl: String,client: OkHttpClient): I{
        val retrofit: Retrofit = retrofitCache[baseUrl] ?: createRetrofit(baseUrl, baseUrl, client)
        val api: I = retrofit.create(service)
        apiCache.put(service,api)
        return api
    }
}


/**
 * 在原有Observable注入调度方法 使Retrofit对象调用接口生成Observable对象后能够执行线性调度
 */
fun <M> Observable<IEntity<M>>.submit(observer: HttpListener<M> = HttpListener()){
    subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer)
}
